/*
 * @(#)XmlCoverterHelper.java
 *
 * Copyright 2012 by ShenY BIS, All rights reserved.
 */

package com.bis.framework.util.xmlConvert;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

/**
 * XmlCoverterHelper
 * 
 * @author BIS 2012-12-24
 */
public abstract class XmlCoverterHelper
{

    /**
     * classPath
     */
    private static final String classPath = "com.common.util.XmlCoverterHelper";

    /**
     * debugLevel
     */
    public enum debugLevel
    {
        ERROR, INFOR, DEBUG;
    }

    /**
     * _logger
     */
    protected Logger         _logger      = null;

    /**
     * _xmlFileName
     */
    protected String         _xmlFileName = null;

    /**
     * _xmlFile
     */
    protected File           _xmlFile     = null;

    /**
     * _document
     */
    protected Document       _document    = null;

    /**
     * _debug
     */
    protected static boolean _debug       = false;

    /**
     * dataList
     */
    protected List           dataList     = null;

    /**
     * @return the dataList
     */
    public List getDataList()
    {
        return dataList;
    }

    /**
     * @param dataList the dataList to set
     */
    public void setDataList(List dataList)
    {
        this.dataList = dataList;
    }

    /**
     * getInstance
     * @Description:
     * @param xmlFileName
     * @param coverterName
     * @param debug
     * @return
     */
    public static XmlCoverterHelper getInstance(String xmlFileName, String coverterName, boolean debug)
    {

        XmlCoverterHelper helper = null;
        BufferedReader bf = null;
        SAXReader sr = new SAXReader();
        Document doc = null;
        File xmlFile = null;
        Class c = null;

        debugNoLog(debugLevel.INFOR, " -> begin getInstance");
        _debug = debug;

        try
        {
            xmlFile = new File(xmlFileName);
            bf = new BufferedReader(new FileReader(xmlFile));
            debugNoLog(debugLevel.INFOR, xmlFileName);
        }
        catch (FileNotFoundException e)
        {
            debugNoLog(debugLevel.ERROR, e);
        }

        try
        {
            doc = sr.read(bf);
        }
        catch (DocumentException e)
        {
            debugNoLog(debugLevel.ERROR, e);
        }
        finally
        {
            try
            {
                bf.close();
            }
            catch (IOException e)
            {
                debugNoLog(debugLevel.ERROR, e);
            }
        }

        try
        {
            c = Class.forName(coverterName);
            helper = (XmlCoverterHelper) c.newInstance();
            debugNoLog(debugLevel.DEBUG, " Instance object : [ " + coverterName + " ]");
        }
        catch (InstantiationException e)
        {
            debugAndLog(null, debugLevel.ERROR, e);
        }
        catch (IllegalAccessException e)
        {
            debugAndLog(null, debugLevel.ERROR, e);
        }
        catch (ClassNotFoundException e)
        {
            debugAndLog(null, debugLevel.ERROR, e);
        }

        helper._xmlFileName = xmlFileName;
        helper._xmlFile = xmlFile;
        helper._logger = Logger.getLogger(c);
        helper._document = doc;

        debugNoLog(debugLevel.INFOR, " -> end getInstance finished !");

        return helper;
    }

    /**
     * debugAndLog
     * @Description:
     * @param obj
     * @param level
     * @param info
     */
    protected static void debugAndLog(XmlCoverterHelper obj, debugLevel level, Object info)
    {

        String objectName = (obj == null) ? " -> " + classPath : " -> " + obj.getClass().getName();

        if (debugLevel.ERROR.equals(level))
        {
            System.err.print("[ Error !!! ]" + objectName);
            System.err.println(info);
            obj._logger.error(info);
        }
        else if (debugLevel.INFOR.equals(level))
        {
            System.out.print("[ Information : ]" + objectName);
            System.out.println(info);
            obj._logger.info(info);
        }
        else if (_debug && debugLevel.DEBUG.equals(level))
        {
            System.out.print("[ Debug : ]" + objectName);
            System.out.println(info);
            obj._logger.debug(info);
        }
    }

    /**
     * debugNoLog
     * @Description:
     * @param level
     * @param info
     */
    private static void debugNoLog(debugLevel level, Object info)
    {
        if (debugLevel.ERROR.equals(level))
        {
            System.err.print("[ Error !!! ]" + classPath);
            System.err.println(info);
        }
        else if (debugLevel.INFOR.equals(level))
        {
            System.out.print("[ Information : ]" + classPath);
            System.out.println(info);
        }
        else if (_debug && debugLevel.DEBUG.equals(level))
        {
            System.out.print("[ Debug : ]" + classPath);
            System.out.println(info);
        }
    }

    /**
     * read
     * @Description:
     */
    public abstract void read();

    /**
     * convert
     * @Description:
     */
    public abstract void convert();

    /**
     * getNodesIterator
     * @Description:
     * @return
     */
    public Iterator getNodesIterator()
    {
        return this._document.nodeIterator();
    }

    /**
     * getElementIterator
     * @Description:
     * @param element
     * @return
     */
    public Iterator getElementIterator(Element element)
    {
        return element.elementIterator();
    }

    /**
     * getAttributeIterator
     * @Description:
     * @param element
     * @return
     */
    public Iterator getAttributeIterator(Element element)
    {
        return element.attributeIterator();
    }
}